package com.px.scserver.service.impl;

import com.alibaba.excel.EasyExcel;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.px.sccommon.exception.ScException;
import com.px.scserver.api.pc.v1.request.JuniorCollegeEnrollmentMajorListRequest;
import com.px.scserver.api.pc.v1.request.JuniorCollegeEnrollmentMajorSaveRequest;
import com.px.scserver.api.pc.v1.vo.ImportJuniorCollegeEnrollmentMajorVO;
import com.px.scserver.api.wx.v1.vo.ExaminationMajorVO;
import com.px.scserver.api.wx.v1.vo.JuniorCollegeEnrollmentMajorVO;
import com.px.scserver.api.wx.v1.vo.JuniorCollegeInfoVO;
import com.px.scserver.api.wx.v1.vo.UndergraduateTypeInfoVO;
import com.px.scserver.converter.JuniorCollegeEnrollmentMajorConverter;
import com.px.scserver.mapper.JuniorCollegeEnrollmentMajorMapper;
import com.px.scserver.po.*;
import com.px.scserver.service.*;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 *
 */
@Slf4j
@Service
@AllArgsConstructor
public class JuniorCollegeEnrollmentMajorServiceImpl extends ServiceImpl<JuniorCollegeEnrollmentMajorMapper, JuniorCollegeEnrollmentMajor>
        implements JuniorCollegeEnrollmentMajorService {

    private final JuniorCollegeToUndergraduateService juniorCollegeToUndergraduateService;
    private final UndergraduateMajorService undergraduateMajorService;
    private final EducationUndergraduateMajorService educationUndergraduateMajorService;
    private final UndergraduateEnrollmentSchoolService undergraduateEnrollmentSchoolService;

    private final JuniorCollegeService juniorCollegeService;
    private final JuniorCollegeEnrollmentMajorConverter converter;

    @Override
    public List<ExaminationMajorVO> getExaminationMajor(String enrollmentMajor, String subjectCategory, String professionalCategory) {
        if (subjectCategory.contains("(")) {
            subjectCategory = subjectCategory.substring(0, subjectCategory.indexOf("("));
        }

        if (professionalCategory.contains("(")) {
            professionalCategory = professionalCategory.substring(0, professionalCategory.indexOf("("));
        }

        String[] split = enrollmentMajor.split("-");
        List<JuniorCollegeToUndergraduate> undergraduateMajorList = new ArrayList<>();

        for (String enrollmentMajorItem : split) {
            if (enrollmentMajorItem.contains("(")) {
                enrollmentMajorItem = enrollmentMajorItem.substring(0, enrollmentMajorItem.indexOf("("));
            }
            undergraduateMajorList.addAll(juniorCollegeToUndergraduateService.getUndergraduateMajor(enrollmentMajorItem));
        }
        undergraduateMajorList.addAll(juniorCollegeToUndergraduateService.getUndergraduateMajor(subjectCategory));
        undergraduateMajorList.addAll(juniorCollegeToUndergraduateService.getUndergraduateMajor(professionalCategory));

        if (CollectionUtils.isEmpty(undergraduateMajorList)) {
            return new ArrayList<>();
        }

        return handlerResult(undergraduateMajorList);
    }

    @Override
    public List<ExaminationMajorVO> getExaminationMajorById(Long juniorCollegeId) {
        List<String> codeList = getCodeList(juniorCollegeId);
        List<JuniorCollegeToUndergraduate> undergraduateMajorList = juniorCollegeToUndergraduateService.getByJuniorCollegeCodes(codeList);
        if (CollectionUtils.isEmpty(undergraduateMajorList)) {
            return new ArrayList<>();
        }

        return handlerResult(undergraduateMajorList);
    }

    @Override
    public List<ExaminationMajorVO> getExaminationMajorByMajorName(String majorName) {
        JuniorCollege college = juniorCollegeService.lambdaQuery()
                .eq(JuniorCollege::getJuniorCollegeName, majorName)
                .one();

        List<String> codeList = getCodeList(college);
        List<JuniorCollegeToUndergraduate> undergraduateMajorList = juniorCollegeToUndergraduateService.getByJuniorCollegeCodes(codeList);
        if (CollectionUtils.isEmpty(undergraduateMajorList)) {
            return new ArrayList<>();
        }

        return getExaminationMajorList(undergraduateMajorList);
    }

    @Override
    public JuniorCollegeInfoVO getJuniorCollegeInfo(Long juniorCollegeId) {
        List<String> codeList = getCodeList(juniorCollegeId);
        JuniorCollegeInfoVO juniorCollegeInfoVO = new JuniorCollegeInfoVO();
        juniorCollegeInfoVO.setJuniorCollege(juniorCollegeService.getById(juniorCollegeId));

        List<String> findCodeList = new ArrayList<>();
        codeList.forEach(code -> {
            if (code.length() == 2 || code.length() == 4) {
                findCodeList.add(code);
            }
        });
        List<JuniorCollegeToUndergraduate> undergraduateMajorList = juniorCollegeToUndergraduateService.getByJuniorCollegeCodes(codeList);

        juniorCollegeInfoVO.setTypeInfoVOList(undergraduateMajorList.stream().map(item -> {
            UndergraduateTypeInfoVO typeInfoVO = new UndergraduateTypeInfoVO();
            typeInfoVO.setUndergraduateCode(item.getUndergraduateCode());
            typeInfoVO.setCodeLength(item.getUndergraduateCode().length());
            typeInfoVO.setSubjectDescription(item.getSubjectDescription());
            typeInfoVO.setUndergraduateName(item.getUndergraduateName());
            return typeInfoVO;
        }).collect(Collectors.toList()));

        return juniorCollegeInfoVO;
    }

    private List<ExaminationMajorVO> handlerResult(List<JuniorCollegeToUndergraduate> undergraduateMajorList) {
        List<ExaminationMajorVO> result = getExaminationMajorList(undergraduateMajorList);

        // 根据上面的专业，找到对应的可考学校
        for (ExaminationMajorVO examinationMajorVO : result) {
            examinationMajorVO.setSchoolLogoUrlList(undergraduateEnrollmentSchoolService.getSchoolLogoUrlListByMajorCode(examinationMajorVO.getMajorCode()));
            examinationMajorVO.setSchoolCount(examinationMajorVO.getSchoolLogoUrlList().size());
        }
        return result.stream().filter(itme -> itme.getSchoolCount() > 0).collect(Collectors.toList());
    }

    private List<ExaminationMajorVO> getExaminationMajorList(List<JuniorCollegeToUndergraduate> undergraduateMajorList) {
        List<String> nameList = new ArrayList<>();
        List<String> nameListF = new ArrayList<>();
        nameList.addAll(undergraduateMajorList.stream()
                .map(item -> {
                    String name = item.getUndergraduateName();
                    if (name.contains("(")) {
                        name = name.substring(0, item.getUndergraduateName().indexOf("("));
                    }
                    if (name.contains("（")) {
                        name = name.substring(0, name.indexOf("（"));
                    }
                    return name;
                }).collect(Collectors.toSet()));

        for (String name : nameList) {
            nameListF.add(name);
            if (name.contains("大类")) {
                nameListF.add(name.replaceAll("大类", ""));
            }
        }
        nameList = nameListF;


        // 去本科表和职教本科表找到专业名称
        List<UndergraduateMajor> undergraduateMajorList_ = undergraduateMajorService.getMajorBy(nameList);
        List<EducationUndergraduateMajor> educationUndergraduateMajorList = educationUndergraduateMajorService.getMajorBy(nameList);

        List<ExaminationMajorVO> result = undergraduateMajorList_.stream().map(item -> {
            ExaminationMajorVO majorVO = new ExaminationMajorVO();
            majorVO.setMajorName(item.getMajorName());
            majorVO.setMajorCode(item.getMajorCode());
            return majorVO;
        }).collect(Collectors.toList());
        result.addAll(educationUndergraduateMajorList.stream().map(item -> {
            ExaminationMajorVO majorVO = new ExaminationMajorVO();
            majorVO.setMajorName(item.getMajorName() + "（职教）");
            majorVO.setMajorCode(item.getMajorCode());
            return majorVO;
        }).collect(Collectors.toList()));

        return result;
    }

    private List<String> getCodeList(Long juniorCollegeId) {
        return getCodeList(juniorCollegeService.getById(juniorCollegeId));
    }

    private List<String> getCodeList(JuniorCollege juniorCollege) {
        List<String> juniorCollegeCodeList = new ArrayList<>();

        if (Objects.isNull(juniorCollege)) {
            throw new ScException("专科数据不存在！");
        }

        juniorCollegeCodeList.add(juniorCollege.getJuniorCollegeCode());

        List<String> codeList = new ArrayList<>();
        for (String juniorCollegeCode : juniorCollegeCodeList) {
            codeList.add(juniorCollegeCode);
            codeList.add(juniorCollegeCode.substring(0, 2));
            codeList.add(juniorCollegeCode.substring(0, 4));
        }
        return codeList;
    }

    @Override
    public List<JuniorCollegeEnrollmentMajorVO> getMajorList(String majorName) {
        List<JuniorCollegeEnrollmentMajorVO> majorVOList = converter.converterListVo(getBaseMapper().getMajorList(majorName));
        majorVOList = handleMajorName(majorVOList);
        return majorVOList;
    }

    private List<JuniorCollegeEnrollmentMajorVO> handleMajorName(List<JuniorCollegeEnrollmentMajorVO> majorVOList) {
        List<JuniorCollegeEnrollmentMajorVO> resultMajorVOList = new ArrayList<>();
        for (JuniorCollegeEnrollmentMajorVO majorVO : majorVOList) {
            if (majorVO.getEnrollmentMajor().contains("-")) {
                String[] split = majorVO.getEnrollmentMajor().split("-");
                JuniorCollegeEnrollmentMajorVO item = new JuniorCollegeEnrollmentMajorVO();
                item.setAbbreviation(split[0]);
                item.setEnrollmentMajor(majorVO.getEnrollmentMajor());
                item.setProfessionalCategory(majorVO.getProfessionalCategory());
                item.setSubjectCategory(majorVO.getSubjectCategory());
                resultMajorVOList.add(item);
            } else {
                resultMajorVOList.add(majorVO);
            }
        }
        return resultMajorVOList;
    }

    @Override
    public void importData(MultipartFile file) {
        List<ImportJuniorCollegeEnrollmentMajorVO> list = new ArrayList<>();
        try {
            list = EasyExcel.read(file.getInputStream()).head(ImportJuniorCollegeEnrollmentMajorVO.class).sheet().doReadSync();
        } catch (Exception e) {
            log.error("入数据有误！", e);
            throw new RuntimeException("导入数据有误！");
        }
        // saveBatch(converter.converterList(list));
        for (var item : converter.converterList(list)) {
            try {
                save(item);
            } catch (Exception e) {
            }
        }
    }

    @Override
    public IPage<com.px.scserver.api.pc.v1.vo.JuniorCollegeEnrollmentMajorVO> page(JuniorCollegeEnrollmentMajorListRequest request) {
        Page<JuniorCollegeEnrollmentMajor> page = lambdaQuery()
                .like(StringUtils.isNotBlank(request.getSchoolName()), JuniorCollegeEnrollmentMajor::getSchoolName, request.getSchoolName())
                .like(StringUtils.isNotBlank(request.getEnrollmentMajor()), JuniorCollegeEnrollmentMajor::getEnrollmentMajor, request.getEnrollmentMajor())
                .page(new Page<>(request.getCurrent(), request.getSize()));
        return page.convert(converter::converterToV2);
    }

    @Override
    public void saveOrUpdate(JuniorCollegeEnrollmentMajorSaveRequest request) {
        JuniorCollegeEnrollmentMajor po = converter.converterRequest(request);
        if (Objects.isNull(po.getId())) {
            save(po);
            return;
        }
        updateById(po);
    }

    @Override
    public List<String> getSchoolName(String schoolName) {
        List<JuniorCollegeEnrollmentMajor> list = lambdaQuery()
                .select(JuniorCollegeEnrollmentMajor::getSchoolName)
                .like(StringUtils.isNotEmpty(schoolName), JuniorCollegeEnrollmentMajor::getSchoolName, schoolName)
                .list();
        if (CollectionUtils.isEmpty(list)) {
            return new ArrayList<>();
        }
        return list.stream()
                .map(JuniorCollegeEnrollmentMajor::getSchoolName)
                .distinct()
                .collect(Collectors.toList());
    }

    @Override
    public List<String> getMajorName(String schoolName, String majorName) {
        List<JuniorCollegeEnrollmentMajor> list = lambdaQuery()
                .select(JuniorCollegeEnrollmentMajor::getEnrollmentMajor)
                .like(StringUtils.isNotEmpty(schoolName), JuniorCollegeEnrollmentMajor::getSchoolName, schoolName)
                .like(StringUtils.isNotEmpty(majorName), JuniorCollegeEnrollmentMajor::getEnrollmentMajor, majorName)
                .list();
        if (CollectionUtils.isEmpty(list)) {
            return new ArrayList<>();
        }
        return list.stream()
                .map(JuniorCollegeEnrollmentMajor::getEnrollmentMajor)
                .distinct()
                .collect(Collectors.toList());
    }
}




